﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;
using C1.Silverlight.RichTextBox;
using Microsoft.Practices.Composite.Events;
using Silverlight.Weblog.Client.CoreBL.Widgets;
using Silverlight.Weblog.Client.DAL.Events;
using Silverlight.Weblog.Client.Default.Widgets.BaseUI;
using Silverlight.Weblog.Client.Default.Widgets.DefaultTheme;
using Silverlight.Weblog.Common.IoC;
using System.Linq;
using Silverlight.Weblog.Client.Default.Widgets;

namespace Silverlight.Weblog.Client.Default.Widgets
{
    [Export(typeof(IBlogWidget))]
	public partial class MultipleBlogPostsWidget : UserControlBase, IDefaultMainWidget
	{
        public IMultipleBlogPostWidgetViewModel ViewModel { get; set; }

		public MultipleBlogPostsWidget()
		{
			// Required to initialize variables
			InitializeComponent();

            //IoC.Get<IEventAggregator>().GetEvent<CommentsExpandedEvent>().Subscribe(CommentsExpanded);

            itemsControl.ItemContainerGenerator.ItemsChanged += new ItemsChangedEventHandler(itemsControl_ItemsChanged);
		}

        /// <summary>
        /// hack: expand the first expander.
        /// </summary>
        private void itemsControl_ItemsChanged(object sender, ItemsChangedEventArgs e)
        {
            if (itemsControl.Items.Any())
            {
                var containerFromItem =  itemsControl.ItemContainerGenerator.ContainerFromItem(itemsControl.Items[0]);
                if (containerFromItem != null)
                {
                    var expander = containerFromItem.GetChildOfType<Expander>();
                    if (expander != null && expander.IsExpanded == false)
                    {
                        expander.IsExpanded = true;
                    }
                }
            }
        }

        //accordion.SelectedItemsChanged += new NotifyCollectionChangedEventHandler(accordion_SelectedItemsChanged);

        //private bool _IsSelectionHackInProgress = false;
        //void accordion_SelectedItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
        //{
        //    if (_IsSelectionHackInProgress == true)
        //        return;
        //    _IsSelectionHackInProgress = true;

        //    // Hack : Resizing accordion items after they've been initialized
        //    if (e.NewItems != null)
        //    foreach (object NewItem in e.NewItems)
        //    {
        //        AccordionItem accordionItemToResize = (AccordionItem)
        //            accordion.ItemContainerGenerator.ContainerFromItem(NewItem);
        //        //bool _isResizeHappens = false;
        //        if (accordionItemToResize != null)
        //        {
        //            //accordionItemToResize.GetChildOfType<C1RichTextBox>().SizeChanged += (s, args)
        //            //    =>
        //            //         {
        //            //             if (!_isResizeHappens)
        //            //             {
        //            //                 _isResizeHappens = true;
        //            //                 UpdateSize(accordionItemToResize);
        //            //             }
        //            //         };
        //            TimerExtensions.In(TimeSpan.FromSeconds(1), () =>
        //                {
        //                    //var ContentSite =
        //                    //    accordionItemToResize.GetChildOfType<ContentPresenter>(c => c.Name == "ContentSite");
        //                    var rtb = accordionItemToResize.GetChildOfType<C1RichTextBox>();
        //                    //accordionItemToResize.Height = rtb.ExtentHeight + 300;
        //                    accordionItemToResize.GetChildOfType<ExpandableContentControl>().Height = rtb.ExtentHeight + 200;
        //            //        accordionItemToResize.UpdateSize();
        //            //        //Size desiredSize = accordionItemToResize.GetChildOfType<C1RichTextBox>().DesiredSize;
        //            //        //accordionItemToResize.GetChildOfType<ExpandableContentControl>().TargetSize =
        //            //        //    new Size(desiredSize.Width, DesiredSize.Height + 200);
        //            //        //accordionItemToResize. =
        //            //        //    accordionItemToResize.GetChildOfType<C1RichTextBox>().DesiredSize;
        //            //        //accordionItemToResize.UpdateSize()
        //                });
        //        }
        //    }

        //    _IsSelectionHackInProgress = false;
        //}

        //void ItemContainerGenerator_ItemsChanged(object sender, ItemsChangedEventArgs e)
        //{
        //    // Hack: Setting Accordion.SelectedIndex=0
        //    if (accordion.Items != null && accordion.Items.Any())
        //        accordion.SelectedIndex = 0;
        //}

        ///// <summary>
        ///// Hack: Componsating for AccordionItems not expanding when the comments area expands. 
        ///// </summary>
        //public void CommentsExpanded(object obj)
        //{
        //    if (_IsSelectionHackInProgress == true)
        //        return;
        //    _IsSelectionHackInProgress = true;

        //    AccordionItem accordionItemToResize = accordion.ItemContainerGenerator.ContainerFromItem(obj) as AccordionItem;
        //    if (accordionItemToResize != null)
        //    {
        //        TimerExtensions.In(TimeSpan.FromSeconds(1), () => accordionItemToResize.UpdateSize());
        //     }

        //    _IsSelectionHackInProgress = false;
        //}

        #region Implementation of IDefaultMainWidget

        public int Priority
        {
            get { return 100; }
        }

        #endregion
	}

    //public static class AccordionItemExtensions
    //{
    //    /// <summary>
    //    /// Forces a selected AccordionItem to resize to its contents.
    //    /// Doesn't work for Accordion.SelectionModes: One, OneOrMore
    //    /// </summary>
    //    /// <param name="item">Selected AccordionItem to udpate.</param>
    //    public static void UpdateSize(this AccordionItem item)
    //    {
    //        item.Dispatcher.BeginInvoke(
    //            delegate
    //            {
    //                if (!item.IsLocked && item.IsSelected)
    //                {
    //                    item.IsSelected = false;
    //                    item.InvokeOnLayoutUpdated(delegate { item.IsSelected = true; });
    //                }
    //            });
    //    }
    //}

    public static class TimerExtensions
    {
        public static void In(TimeSpan fromSeconds, Action action)
        {
            DispatcherTimer timer = new DispatcherTimer() { Interval = fromSeconds };
            timer.Tick += (s, args) =>
            {
                action();
                timer.Stop();
            };
            timer.Start();
        }
    }

    public static class VisualTreeExtensions
    {
        public static T GetChildOfType<T>(this DependencyObject element)
            where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
            {
                var currentChild = VisualTreeHelper.GetChild(element, i);
                if (currentChild is T)
                    return (T)currentChild;
                else
                {
                    var nestedChild = GetChildOfType<T>(currentChild);
                    if (nestedChild != null)
                        return nestedChild;
                }
            }
            return null;
        }

        public static List<T> GetChildrenOfType<T>(this DependencyObject element)
    where T : DependencyObject
        {
            List<T> ReturnValues = new List<T>();
            GetChildrenOfType(element, ReturnValues);
            return ReturnValues;
        }

        private static void GetChildrenOfType<T>(DependencyObject element, List<T> ReturnValues)
            where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
            {
                var currentChild = VisualTreeHelper.GetChild(element, i);
                if (currentChild is T && currentChild != null)
                    ReturnValues.Add((T)currentChild);
                else
                {
                    GetChildrenOfType<T>(currentChild, ReturnValues);
                }
            }
        }

        public static T GetChildOfType<T>(this DependencyObject element, Func<T, bool> condition)
            where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
            {
                var currentChild = VisualTreeHelper.GetChild(element, i);
                if (currentChild is T && condition((T) currentChild))
                    return (T)currentChild;
                else
                {
                    var nestedChild = GetChildOfType<T>(currentChild, condition);
                    if (nestedChild != null)
                        return nestedChild;
                }
            }
            return null;
        }
    }
}